package com.ruix.app.network;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import com.alibaba.sdk.android.oss.OSS;
import com.hyphenate.util.NetUtils;
import com.ruix.app.RuiApplication;
import com.ruix.app.constant.RuiXConstant;
import com.ruix.app.mapper.ApiMapper;
import com.ruix.app.model.ImageUpload;
import com.ruix.app.network.exception.NetworkUnusableException;
import com.ruix.app.network.exception.PermissionException;
import com.ruix.app.network.exception.RequestApiException;
import com.ruix.app.network.exception.SendTimeException;
import com.ruix.app.network.exception.TokenExpiredException;
import com.ruix.app.network.request.RXPostFormRequst;
import com.ruix.app.network.response.RXResponse;
import com.ruix.app.util.LogUitl;
//import com.zhy.http.okhttp.OkHttpUtils;
//import com.zhy.http.okhttp.builder.OkHttpRequestBuilder;

import org.json.JSONObject;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Response;

/**
 * Created by hadexs on 2017/4/13.
 */

public class BaseRequestFactory {


    // 请求接口 返回JSONObject［无mapper］
    public static Observable<JSONObject> requstForJSONObject(final RequestParams requestParams) {
        return Observable.create(new ObservableOnSubscribe<JSONObject>() {
            @Override
            public void subscribe(ObservableEmitter<JSONObject> emitter) throws Exception {
                if (RequestManager.isNetOk) {
                    try {
                        if (requestParams == null) {
                            emitter.onError(new RequestApiException("params is null"));
                        }
                        RXPostFormRequst rxRequest = new RXPostFormRequst(requestParams);
                        Response response = RequestManager.okhttpClient.newCall(rxRequest.buildRequst()).execute();
                        RXResponse rxRespons = new RXResponse(response, rxRequest);
                        if (rxRespons.isSuccess()) {
                            emitter.onNext(rxRespons.getResponseJSONObject());
                        } else {
                            if (rxRespons.getCode() == 10003 || rxRespons.getCode() ==10080) {
                                emitter.onError(new TokenExpiredException(""));
                            }else if (rxRespons.getCode() == 10083){
                                emitter.onError(new PermissionException(""));
                            }else if (rxRespons.getCode() == 10084){
                                emitter.onError(new SendTimeException(""));
                            } else {
                                emitter.onError(new RequestApiException(rxRespons.getCode(), rxRespons.getMsg()));
                            }
                        }
                    } catch (Exception e) {
                        LogUitl.e("RuiX", e.getMessage());
                        emitter.onError(e);
                    }
                } else {
                    emitter.onError(new NetworkUnusableException());
                }
                emitter.onComplete();
            }
        });
    }


    // 请求接口 返回JSONObject［无mapper］
    public static Observable<Bitmap> requstForString(final RequestParams requestParams) {
        return Observable.create(new ObservableOnSubscribe<Bitmap>() {
            @Override
            public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
                if (RequestManager.isNetOk) {
                    try {
                        if (requestParams == null) {
                            emitter.onError(new RequestApiException("params is null"));
                        }
                        RXPostFormRequst rxRequest = new RXPostFormRequst(requestParams);
                        Response response = RequestManager.okhttpClient.newCall(rxRequest.buildRequst()).execute();
                        RXResponse rxRespons = new RXResponse(response, rxRequest);

                        if (response.code() == 200) {
                            byte[] bytes = response.body().bytes();
                            bytes = Base64.decode(bytes, Base64.DEFAULT);
                            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                            emitter.onNext(bitmap);
                        } else {
                            emitter.onError(new RequestApiException(rxRespons.getCode(), rxRespons.getMsg()));
                        }
                    } catch (Exception e) {
                        emitter.onError(e);
                    }
                } else {
                    emitter.onError(new NetworkUnusableException());
                }
                emitter.onComplete();
            }
        });
    }


    protected static void execute(RequestParams requestParams, Observer observer) {
        // 被观察者：Observable［发送请求］
        // 订阅者或观察者：Subscriber对Observer接口进行扩展［接受返回后处理］
        // 订阅或注册方法：subscribe()
        requstForJSONObjects(requestParams)
                .subscribeOn(Schedulers.io())// 指定 subscribe() 发生在新的线程，即事件产生的线程［无数量上限的线程池］
                .observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回调发生在Android主线程，即事件消费的线程
                .subscribe(observer);
    }



    protected static <T> void execute(RequestParams requestParams, final ApiMapper<T> mapper, Observer<T> observer) {

        if (mapper != null) {
            Function<JSONObject, T> transformer = new Function<JSONObject, T>() {

                @Override
                public T apply(JSONObject jsonObject) throws Exception {
                    return mapper.transform(jsonObject);
                }
            };
            requstForJSONObject(requestParams)
                    .subscribeOn(Schedulers.io())
                    .map(transformer)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observer);
        } else {
            execute(requestParams, observer);
        }
    }

    protected static void execute(Observable observable, Observer observer) {
        observable.subscribeOn(Schedulers.io())// 指定 subscribe() 发生在新的线程，即事件产生的线程［无数量上限的线程池］
                .observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回调发生在Android主线程，即事件消费的线程
                .subscribe(observer);
    }

    // 请求接口 返回JSONObject［无mapper］
    public static Observable<JSONObject> requstForJSONObjects(final RequestParams requestParams) {
        return Observable.create(new ObservableOnSubscribe<JSONObject>() {
            @Override
            public void subscribe(ObservableEmitter<JSONObject> emitter) throws Exception {
                if (RequestManager.isNetOk) {
                    try {
                        if (requestParams == null) {
                            emitter.onError(new RequestApiException("params is null"));
                        }
                        RXPostFormRequst rxRequest = new RXPostFormRequst(requestParams);
                        Response response = RequestManager.okhttpClient.newCall(rxRequest.buildRequst()).execute();
                        RXResponse rxRespons = new RXResponse(response, rxRequest);

                        if (rxRespons.isSuccess()) {
                            emitter.onNext(rxRespons.getResponseJSONObject());
                        } else {
                            if (rxRespons.getCode() == 10003 || rxRespons.getCode() ==10080) {
                                emitter.onError(new TokenExpiredException(""));
                            }else if (rxRespons.getCode() == 10083){
                                emitter.onError(new PermissionException(""));
                            }else if (rxRespons.getCode() == 10084){
                                emitter.onError(new SendTimeException(""));
                            } else {
                                emitter.onError(new RequestApiException(rxRespons.getCode(), rxRespons.getMsg()));
                            }

                        }
                    } catch (Exception e) {
                        emitter.onError(e);
                    }
                } else {
                    emitter.onError(new NetworkUnusableException());
                }
                emitter.onComplete();
            }
        });
    }


    // 请求接口 返回JSONObject［无mapper］
    public static Observable<ArrayList<String>> albUploadFileObservale(final ALUploadFileParam alUploadFileParam) {
        return Observable.create(new ObservableOnSubscribe<ArrayList<String>>() {
            @Override
            public void subscribe(ObservableEmitter<ArrayList<String>> emitter) throws Exception {
                if (RequestManager.isNetOk) {
                    try {
                        if (alUploadFileParam == null || !alUploadFileParam.canUpload()) {
                            emitter.onError(new RequestApiException("params is null"));
                        }
                        ArrayList<String> pathes = alUploadFileParam.getPathes();
                        ArrayList<String> uploadPathes = new ArrayList<String>();

                        for (int i = 0; i < pathes.size(); i++) {
                            OSS oss = alUploadFileParam.getOssClient();
                            String bucketName = alUploadFileParam.getOssToken().getBucketName();
                            String path = pathes.get(i);
                            String objectName = alUploadFileParam.getObjectName(path);
                            new MultipartUploadSamples(oss, bucketName, objectName, path).multipartCompressUpload();
                            uploadPathes.add(objectName);
                        }
                        if (uploadPathes.size() > 0) {
                            emitter.onNext(uploadPathes);
                        } else {
                            emitter.onError(new RequestApiException("网络不畅通"));
                        }
                    } catch (Exception e) {
                        emitter.onError(e);
                    }
                } else {
                    emitter.onError(new NetworkUnusableException());
                }
                emitter.onComplete();
            }
        });
    }


    // 请求接口 返回JSONObject［无mapper］
    public static Observable<ArrayList<String>> albUploadVoiceFileObservale(final ALUploadFileParam alUploadFileParam) {
        return Observable.create(new ObservableOnSubscribe<ArrayList<String>>() {
            @Override
            public void subscribe(ObservableEmitter<ArrayList<String>> emitter) throws Exception {
                if (RequestManager.isNetOk) {
                    try {
                        if (alUploadFileParam == null || !alUploadFileParam.canUpload()) {
                            emitter.onError(new RequestApiException("params is null"));
                        }
                        ArrayList<String> pathes = alUploadFileParam.getPathes();
                        ArrayList<String> uploadPathes = new ArrayList<String>();
                        ImageUpload imageUpload = new ImageUpload();


                        for (int i = 0; i < pathes.size(); i++) {
                            OSS oss = alUploadFileParam.getOssClient();
                            String bucketName = alUploadFileParam.getOssToken().getBucketName();
                            String path = pathes.get(i);
                            String objectName = alUploadFileParam.getObjectName(path);
                            new MultipartUploadSamples(oss, bucketName, objectName, path).multipartUpload();
                            uploadPathes.add(objectName);

                            imageUpload.setLoaclPath(path);

                            uploadPathes.add(objectName);


                        }
                        if (uploadPathes.size() > 0) {
                            emitter.onNext(uploadPathes);
                        } else {
                            emitter.onError(new RequestApiException("网络不畅通"));
                        }
                    } catch (Exception e) {
                        emitter.onError(e);
                    }
                } else {
                    emitter.onError(new NetworkUnusableException());
                }
                emitter.onComplete();
            }
        });
    }



}
